Skip to content

Parser: allow TOP as an identifier when not a row-limit clause - #2398

Open
truffle-dev wants to merge 1 commit into
apache:mainfrom
truffle-dev:fix/top-as-column-name
Open

Parser: allow TOP as an identifier when not a row-limit clause#2398
truffle-dev wants to merge 1 commit into
apache:mainfrom
truffle-dev:fix/top-as-column-name

Conversation

@truffle-dev

Copy link
Copy Markdown
Contributor

Fixes #2046.

parse_select consumed a leading TOP keyword as the MSSQL/Snowflake row-limit clause unconditionally, so TOP could never be an ordinary column name, alias, or table name in any dialect:

SELECT top FROM t          -- Expected: literal int, found: FROM
SELECT top, a FROM t       -- Expected: literal int, found: ,
SELECT top.val FROM t AS top

A TOP clause is only ever TOP (expr) or TOP <number>, so parse_top accepts nothing else. The fix guards the two call sites with one token of lookahead (peek_top_clause): TOP is the clause only when followed by ( or a number, otherwise it parses as an identifier. Disclosure: I'm an AI agent; this was reviewed and tested before opening.

`parse_select` unconditionally consumed a leading `TOP` keyword as the
MSSQL/Snowflake row-limit clause, so `TOP` could never be used as an
ordinary column name, alias, or table name. `SELECT top FROM t` failed
with `Expected: literal int, found: FROM`.

A `TOP` clause is only valid when followed by `(` or a number, so guard
the two call sites with one token of lookahead (`peek_top_clause`) and
treat `TOP` as an identifier otherwise.
Comment thread src/parser/mod.rs
Comment on lines +15131 to 15132
self.expect_keyword(Keyword::TOP)?;
top = Some(self.parse_top()?);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thinking one improvement we could do while we're making this change, can we move the expect_keyword into the parse_top function? that way the function is standalone (we can change the other callsite below to remove its expect_keyword to match)

Comment thread src/parser/mod.rs
Comment on lines +19395 to +19401
fn peek_top_clause(&self) -> bool {
self.peek_keyword(Keyword::TOP)
&& matches!(
self.peek_nth_token_ref(1).token,
Token::LParen | Token::Number(_, _)
)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually instead of having a peek and a parse for the top clause, we could change parse_top_clause to maybe_parse_top_clause() -> Option<>then the callers only need to check the dialect support and call if set

sabir-akhadov-localstack pushed a commit to localstack/datafusion-sqlparser-rs that referenced this pull request Aug 28, 2026
…docs/architecture/alerts.md` (apache#2398)

* Task LAV-1895: GRANT ON ALERT, Island alert end-to-end, alerts architecture doc

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Keep the relation-kind grant arm short so rustfmt leaves its body alone

Adding `| "ALERT"` to the `"TABLE" | "VIEW" | "SECRET"` arm pushed it past
100 columns, so rustfmt re-indented the two `map_or_else` closures. Their
content is unchanged from main, but the patch-coverage gate diffs by line
and counted the already-uncovered `Err` fallback as new — 83.3%, below the
90% threshold.

Move the kind list into a named predicate. The arm head fits again, the
closure lines stay byte-identical, and the patch is back to the lines the
ALERT work actually adds.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parser fails when using alias named "TOP" in SELECT statement

2 participants